<template>
  <div id="devicePlayer" v-loading="isLoading" :style="{ height: !isDialog ? height : 'auto' }">
    <!-- Dialog Mode -->
    <el-dialog
      v-if="isDialog"
      v-el-drag-dialog
      title="视频播放"
      top="5vh"
      width="80%"
      :close-on-click-modal="false"
      :visible.sync="showVideoDialog"
      @close="closeDialog()"
      custom-class="video-player-dialog"
      center
    >
      <div :style="{ width: '100%', height: height }">
        <!-- 使用iframe嵌入播放器 -->
        <iframe 
          v-if="showVideoDialog && iframeUrl !== 'about:blank'"
          ref="videoIframeDialog"
          class="video-iframe"
          :src="iframeUrl" 
          frameborder="0"
          style="width: 100%; height: 100%;"
          allowfullscreen
          allow="autoplay"
        ></iframe>
      </div>
      <div id="shared" style="text-align: right; margin-top: 1rem;">
        <el-tabs v-model="tabActiveName">
          <el-tab-pane label="实时视频" name="media">
            <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
              <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址：</span>
              <el-input v-model="getPlayerShared.sharedUrl" :disabled="true">
                <template slot="append">
                  <i
                    class="cpoy-btn el-icon-document-copy"
                    title="点击拷贝"
                    style="cursor: pointer"
                    @click="copyUrl(getPlayerShared.sharedUrl)"
                  />
                </template>
              </el-input>
            </div>
            <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
              <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址：</span>
              <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true">
                <el-button
                  slot="append"
                  icon="el-icon-document-copy"
                  title="点击拷贝"
                  style="cursor: pointer"
                  @click="copyUrl(getPlayerShared.sharedRtmp)"
                />
                <el-dropdown v-if="internalStreamInfo" slot="prepend" trigger="click" @command="copyUrl">
                  <el-button>
                    更多地址<i class="el-icon-arrow-down el-icon--right" />
                  </el-button>
                  <el-dropdown-menu>
                    <el-dropdown-item v-if="internalStreamInfo.hls" :command="internalStreamInfo.hls">
                      <el-tag>HLS:</el-tag>
                      <span>{{ internalStreamInfo.hls }}</span>
                    </el-dropdown-item>
                    <el-dropdown-item v-if="internalStreamInfo.https_hls" :command="internalStreamInfo.https_hls">
                      <el-tag>HLS(https):</el-tag>
                      <span>{{ internalStreamInfo.https_hls }}</span>
                    </el-dropdown-item>
                    <el-dropdown-item v-if="internalStreamInfo.flv" :command="internalStreamInfo.flv">
                      <el-tag>FLV:</el-tag>
                      <span>{{ internalStreamInfo.flv }}</span>
                    </el-dropdown-item>
                    <el-dropdown-item v-if="internalStreamInfo.ws_flv" :command="internalStreamInfo.ws_flv">
                      <el-tag>FLV(ws):</el-tag>
                      <span>{{ internalStreamInfo.ws_flv }}</span>
                    </el-dropdown-item>
                    <el-dropdown-item v-if="internalStreamInfo.rtmp" :command="internalStreamInfo.rtmp">
                      <el-tag>RTMP:</el-tag>
                      <span>{{ internalStreamInfo.rtmp }}</span>
                    </el-dropdown-item>
                    <el-dropdown-item v-if="internalStreamInfo.rtsp" :command="internalStreamInfo.rtsp">
                      <el-tag>RTSP:</el-tag>
                      <span>{{ internalStreamInfo.rtsp }}</span>
                    </el-dropdown-item>
                    <el-dropdown-item v-if="internalStreamInfo.test_flv" :command="internalStreamInfo.test_flv">
                      <el-tag>测试流:</el-tag>
                      <span>{{ internalStreamInfo.test_flv }}</span>
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
              </el-input>
            </div>
            <div v-if="videoError" class="error-message">
              <el-alert
                :title="videoError"
                type="error"
                show-icon
                :closable="false"
              />
            </div>
            <div style="margin-top: 10px;">
              <el-button size="small" type="warning" @click="refreshPlayer">刷新播放器</el-button>
            </div>
          </el-tab-pane>
          <!-- 添加云台控制标签页 -->
          <el-tab-pane label="云台控制" name="control">
            <div style="display: grid; grid-template-columns: 240px auto; height: 180px; overflow: auto">
              <div class="control-wrapper">
                <div class="control-btn control-top" 
                     @mousedown="ptzCamera('up')" 
                     @mouseup="ptzCamera('stop')"
                     @mouseleave="ptzCamera('stop')"
                     @touchstart="ptzCamera('up')" 
                     @touchend="ptzCamera('stop')"
                     @touchcancel="ptzCamera('stop')">
                  <i class="el-icon-caret-top" />
                  <div class="control-inner-btn control-inner" />
                </div>
                <div class="control-btn control-left" 
                     @mousedown="ptzCamera('left')" 
                     @mouseup="ptzCamera('stop')"
                     @mouseleave="ptzCamera('stop')"
                     @touchstart="ptzCamera('left')" 
                     @touchend="ptzCamera('stop')"
                     @touchcancel="ptzCamera('stop')">
                  <i class="el-icon-caret-left" />
                  <div class="control-inner-btn control-inner" />
                </div>
                <div class="control-btn control-bottom" 
                     @mousedown="ptzCamera('down')" 
                     @mouseup="ptzCamera('stop')"
                     @mouseleave="ptzCamera('stop')"
                     @touchstart="ptzCamera('down')" 
                     @touchend="ptzCamera('stop')"
                     @touchcancel="ptzCamera('stop')">
                  <i class="el-icon-caret-bottom" />
                  <div class="control-inner-btn control-inner" />
                </div>
                <div class="control-btn control-right" 
                     @mousedown="ptzCamera('right')" 
                     @mouseup="ptzCamera('stop')"
                     @mouseleave="ptzCamera('stop')"
                     @touchstart="ptzCamera('right')" 
                     @touchend="ptzCamera('stop')"
                     @touchcancel="ptzCamera('stop')">
                  <i class="el-icon-caret-right" />
                  <div class="control-inner-btn control-inner" />
                </div>
                <div class="control-round">
                  <div class="control-round-inner"><i class="el-icon-video-pause" /></div>
                </div>
                <div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 6.25rem;">
                  <el-slider v-model="controSpeed" :max="100" />
                </div>
              </div>
              <!-- 已移除放大和缩小按钮 -->
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-dialog>

    <!-- Inline Mode -->
    <div v-if="!isDialog" style="width: 100%; height: 100%; position: relative;">
      <iframe
        v-if="iframeUrl !== 'about:blank'"
        ref="videoIframeInline"
        class="video-iframe"
        :src="iframeUrl"
        frameborder="0"
        style="width: 100%; height: 100%;"
        allowfullscreen
        allow="autoplay"
      ></iframe>
      <div v-if="videoError" class="error-message-inline">
        <el-alert
          :title="videoError"
          type="error"
          show-icon
          :closable="false"
        />
      </div>
    </div>
  </div>
</template>

<script>
import elDragDialog from '@/directive/dialog/elDragDialog'

export default {
  name: 'DevicePlayer',
  directives: { elDragDialog },
  props: {
    // 视频URL
    videoUrl: {
      type: String,
      default: ''
    },
    // 是否为弹窗模式
    isDialog: {
      type: Boolean,
      default: true
    },
    // 是否自动播放
    autoplay: {
      type: Boolean,
      default: true
    },
    // 是否为直播
    live: {
      type: Boolean,
      default: true
    },
    // 播放器高度
    height: {
      type: String,
      default: '400px'
    },
    // 完整的流信息（用于弹窗模式）
    streamInfo: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      internalStreamInfo: null, // 内部流信息副本
      iframeUrl: 'about:blank',
      videoError: '',
      showVideoDialog: false,
      streamId: '',
      mediaServerId: '',
      tabActiveName: 'media',
      hasAudio: false,
      isLoading: false,
      messageHandler: null,
      showPtz: true,
      controSpeed: 50,
      deviceId: '',
      channelId: '',
      ptzCommandInterval: null,
      currentPtzCommand: null,
      ptzIntervalDelay: 300
    }
  },
  computed: {
    getPlayerShared: function() {
      return {
        sharedUrl: window.location.origin + '/#/play/video/' + encodeURIComponent(this.videoUrl),
        // 在内联模式下，videoUrl就是完整的流地址
        sharedRtmp: this.isDialog ? (this.internalStreamInfo ? this.internalStreamInfo.rtmp : this.videoUrl) : this.videoUrl
      }
    }
  },
  watch: {
    streamInfo: {
      handler(newVal) {
        this.internalStreamInfo = newVal
      },
      immediate: true,
      deep: true
    },
    videoUrl: {
      handler(newUrl, oldUrl) {
        // 在内联模式下，当videoUrl变化时，自动播放
        if (!this.isDialog && newUrl) {
          if (newUrl !== oldUrl) {
            this.startInlinePlay(newUrl);
          }
        }
      },
      immediate: true
    }
  },
  mounted() {
    // 如果是内联模式，并且初始时就有videoUrl，则直接播放
    if (!this.isDialog && this.videoUrl) {
      this.startInlinePlay(this.videoUrl);
    }
    
    // 监听来自iframe的消息
    this.messageHandler = (event) => {
      if (event.data && event.data.type === 'playError') {
        this.videoError = event.data.message;
        console.error('收到来自播放器的错误:', this.videoError);
      }
    };
    window.addEventListener('message', this.messageHandler);
  },
  beforeDestroy() {
    // 组件销毁前清理
    this.close();
    window.removeEventListener('message', this.messageHandler);
  },
  methods: {
    // Public method to start playback in inline mode
    startInlinePlay(url) {
      console.log(`[devicePlayer] Inline mode: start playing ${url}`);
      this.isLoading = true;
      this.videoError = '';
      this.prepareIframePlayer(url);
    },

    openDialog: function(tab, deviceId, streamInfo, hasAudio) {
      // This method is only for dialog mode
      if (!this.isDialog) {
        console.warn("[devicePlayer] openDialog is called in non-dialog mode.");
        return;
      }
      if (this.showVideoDialog) {
        return;
      }
      
      console.log('打开播放器对话框', tab, deviceId);
      
      this.tabActiveName = tab;
      this.mediaServerId = deviceId;
      this.videoError = '';
      
      // 设置设备ID和通道ID
      if (streamInfo && streamInfo.deviceId) {
        this.deviceId = streamInfo.deviceId;
      }
      if (streamInfo && streamInfo.channelId) {
        this.channelId = streamInfo.channelId;
      }
      
      // 始终启用云台控制
      this.showPtz = true;
      
        this.play(streamInfo, hasAudio);
    },
    play: function(streamInfo, hasAudio) {
      this.internalStreamInfo = streamInfo;
      this.hasAudio = hasAudio;
      this.isLoading = false;
      this.videoError = '';
      
      // 记录流信息到控制台，方便调试
      console.log('播放流信息:', JSON.stringify(streamInfo));
      
      // 找到第一个有效的流地址
      let urlToPlay = this.getPreferredUrl(streamInfo);

      if (!urlToPlay) {
        this.videoError = '没有找到有效的流地址';
        console.error(this.videoError);
        return;
      }
      
      this.streamId = streamInfo.stream;
      this.showVideoDialog = true;
      
      // 准备iframe播放器
      this.prepareIframePlayer(urlToPlay);
    },
    
    getPreferredUrl(streamInfo) {
      if (!streamInfo) return null;
      // 定义流类型优先级
      const urlPriority = [
        'hls', 'https_hls', 'ws_flv', 'wss_flv', 'flv', 'https_flv',
        'rtc', 'rtcs', 'rtmp', 'fmp4', 'ws_fmp4', 'rtsp'
      ];
      for (const key of urlPriority) {
        if (streamInfo[key]) {
          console.log(`选择播放地址 (类型: ${key}): ${streamInfo[key]}`);
          return streamInfo[key];
        }
      }
      return null;
    },

    // 准备iframe播放器 (已重构)
    prepareIframePlayer(url) {
      // 检查URL是否有效
      if (!url || typeof url !== 'string') {
        this.videoError = '无效的播放地址';
        console.error(this.videoError);
          this.isLoading = false;
          return;
          }
      
      this.isLoading = true;
      let finalUrl = '';
      
      // 对于WebRTC，它是一个页面而不是一个媒体流，所以直接使用
      if (url.includes('/index/api/webrtc')) {
        finalUrl = url;
              } else {
        // 对于其他流类型，使用我们新的player.html
        finalUrl = `/html/player.html?src=${encodeURIComponent(url)}&hasAudio=${this.hasAudio}`;
      }

      console.log('设置iframeUrl:', finalUrl);

      // 先重置，再在nextTick中设置新url，确保iframe被重新渲染
      this.iframeUrl = 'about:blank';
      this.$nextTick(() => {
        this.iframeUrl = finalUrl;
        this.isLoading = false;
      });
    },

    closeDialog: function() {
      this.showVideoDialog = false;
      this.close(); // 调用通用的清理方法
    },

    // 公共的关闭和清理方法
    close: function() {
      console.log('[devicePlayer] closing player...');
      this.videoError = '';
      this.isLoading = false;
      
      // 重置iframe URL, 这将自动销毁iframe内的所有内容
      this.iframeUrl = 'about:blank';
    },
    
    // 刷新播放器
    refreshPlayer: function() {
      if (this.iframeUrl && this.iframeUrl !== 'about:blank') {
        console.log('刷新播放器:', this.iframeUrl);
        // 通过给URL添加一个时间戳来强制刷新iframe
        const refreshUrl = this.iframeUrl.includes('?') 
          ? `${this.iframeUrl}&t=${Date.now()}`
          : `${this.iframeUrl}?t=${Date.now()}`;
        this.prepareIframePlayer(refreshUrl);
          }
    },
    
    copyUrl: function(url) {
      if (navigator.clipboard && window.isSecureContext) {
        // 使用现代的Clipboard API
        navigator.clipboard.writeText(url).then(() => {
          this.$message.success({
            showClose: true,
            message: '成功拷贝到粘贴板'
          });
        }).catch(() => {
          this.$message.error({
            showClose: true,
            message: '复制失败'
          });
        });
      } else {
        // 降级到传统方法
        const textarea = document.createElement('textarea');
        textarea.value = url;
        document.body.appendChild(textarea);
        textarea.select();
        try {
          document.execCommand('copy');
          this.$message.success({
            showClose: true,
            message: '成功拷贝到粘贴板'
          });
        } catch (err) {
          this.$message.error({
            showClose: true,
            message: '复制失败'
          });
        }
        document.body.removeChild(textarea);
      }
    },

    // 开始云台控制
    startPtzControl(command) {
      // 清除可能存在的之前的定时器
      this.stopPtzControl();
      
      // 记录当前命令
      this.currentPtzCommand = command;
      
      // 立即执行一次命令
      this.executePtzCommand(command);
      
      // 设置定时器，持续发送命令
      this.ptzCommandInterval = setInterval(() => {
        this.executePtzCommand(command);
      }, this.ptzIntervalDelay);
    },
    
    // 停止云台控制
    stopPtzControl() {
      if (this.ptzCommandInterval) {
        clearInterval(this.ptzCommandInterval);
        this.ptzCommandInterval = null;
      }
      
      // 如果有正在执行的命令，发送停止命令
      if (this.currentPtzCommand) {
        this.executePtzCommand('stop');
        this.currentPtzCommand = null;
      }
    },
    
    // 执行云台控制命令
    executePtzCommand(command) {
      // 实现云台控制逻辑
        if (!this.deviceId || !this.channelId) {
          this.$message.error('无法进行云台控制，缺少设备信息');
          this.stopPtzControl(); // 停止长按控制
          return;
      }
      
      console.log(`云台控制: 设备=${this.deviceId}, 通道=${this.channelId}, 命令=${command}, 速度=${this.controSpeed}`);
        
      // 调用WVP的云台控制API
      const speed = parseInt(this.controSpeed * 255 / 100); // 转换速度范围从0-100到0-255
      const horizonSpeed = speed;
      const verticalSpeed = speed;
      const zoomSpeed = parseInt(this.controSpeed * 16 / 100); // 缩放速度更小
      
      import('@/utils/wvpRequest').then(module => {
        const { ptzControl } = module;
        ptzControl(
          this.deviceId,
          this.channelId,
          command,
          horizonSpeed,
          verticalSpeed,
          zoomSpeed
        ).then(() => {
          if (command !== 'stop' && !this.ptzCommandInterval) {
            // this.$message.success('云台控制命令已发送');
          }
        }).catch(error => {
          console.error('云台控制失败:', error);
          this.$message.error('云台控制失败: ' + (error.message || '未知错误'));
          this.stopPtzControl(); // 出错时停止长按控制
        });
      }).catch(error => {
        console.error('加载云台控制模块失败:', error);
        this.$message.error('云台控制模块加载失败');
        this.stopPtzControl(); // 出错时停止长按控制
      });
    },
    
    // 原来的ptzCamera方法改为使用新的长按控制方法
    ptzCamera(command) {
      if (command === 'stop') {
        this.stopPtzControl();
      } else {
        this.startPtzControl(command);
      }
    }
  }
}
</script>

<style>
.video-iframe {
  width: 100%;
  height: 100%;
  border: none;
  background-color: #000;
}
.control-wrapper {
  position: relative;
  width: 6.25rem;
  height: 6.25rem;
  max-width: 6.25rem;
  max-height: 6.25rem;
  border-radius: 100%;
  margin-top: 1.5rem;
  margin-left: 0.5rem;
  float: left;
}
.control-btn {
  display: flex;
  justify-content: center;
  position: absolute;
  width: 44%;
  height: 44%;
  border-radius: 5px;
  border: 1px solid #78aee4;
  box-sizing: border-box;
  transition: all 0.3s linear;
}
.control-btn:hover {
  cursor: pointer;
  background-color: #ecf5ff;
}
.control-btn i {
  font-size: 20px;
  color: #78aee4;
  display: flex;
  justify-content: center;
  align-items: center;
}
.control-round {
  position: absolute;
  top: 21%;
  left: 21%;
  width: 58%;
  height: 58%;
  background: #fff;
  border-radius: 100%;
}
.control-round-inner {
  position: absolute;
  left: 13%;
  top: 13%;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 70%;
  height: 70%;
  font-size: 40px;
  color: #78aee4;
  border: 1px solid #78aee4;
  border-radius: 100%;
  transition: all 0.3s linear;
}
.control-inner-btn {
  position: absolute;
  width: 60%;
  height: 60%;
  background: #fafafa;
}
.control-top {
  top: -8%;
  left: 27%;
  transform: rotate(-45deg);
  border-radius: 5px 100% 5px 0;
}
.control-top i {
  transform: rotate(45deg);
}
.control-top .control-inner {
  left: -1px;
  bottom: 0;
  border-top: 1px solid #78aee4;
  border-right: 1px solid #78aee4;
  border-radius: 0 100% 0 0;
}
.control-left {
  top: 27%;
  left: -8%;
  transform: rotate(45deg);
  border-radius: 5px 0 5px 100%;
}
.control-left i {
  transform: rotate(-45deg);
}
.control-left .control-inner {
  right: -1px;
  top: -1px;
  border-bottom: 1px solid #78aee4;
  border-left: 1px solid #78aee4;
  border-radius: 0 0 0 100%;
}
.control-right {
  top: 27%;
  right: -8%;
  transform: rotate(45deg);
  border-radius: 5px 100% 5px 0;
}
.control-right i {
  transform: rotate(-45deg);
}
.control-right .control-inner {
  left: -1px;
  bottom: -1px;
  border-top: 1px solid #78aee4;
  border-right: 1px solid #78aee4;
  border-radius: 0 100% 0 0;
}
.control-bottom {
  left: 27%;
  bottom: -8%;
  transform: rotate(45deg);
  border-radius: 0 5px 100% 5px;
}
.control-bottom i {
  transform: rotate(-45deg);
}
.control-bottom .control-inner {
  top: -1px;
  left: -1px;
  border-bottom: 1px solid #78aee4;
  border-right: 1px solid #78aee4;
  border-radius: 0 0 100% 0;
}
.control-zoom-btn:hover {
  cursor: pointer;
  color: #409EFF;
}
.ptz-btn-box {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 0 2rem;
  height: 3rem;
  line-height: 4rem;
}

/* 视频播放器弹窗样式优化 */
.el-dialog__wrapper.video-player-dialog {
  border-radius: 8px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.el-dialog__wrapper.video-player-dialog .el-dialog {
  margin: 0 auto !important;
  border-radius: 8px;
  overflow: hidden;
}

.el-dialog__wrapper.video-player-dialog .el-dialog__header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px;
  border-radius: 8px 8px 0 0;
}

.el-dialog__wrapper.video-player-dialog .el-dialog__title {
  color: white;
  font-weight: 600;
  font-size: 16px;
}

.el-dialog__wrapper.video-player-dialog .el-dialog__headerbtn {
  top: 18px;
  right: 20px;
}

.el-dialog__wrapper.video-player-dialog .el-dialog__headerbtn .el-dialog__close {
  color: white;
  font-size: 18px;
}

.el-dialog__wrapper.video-player-dialog .el-dialog__headerbtn .el-dialog__close:hover {
  color: #f0f0f0;
}

.el-dialog__wrapper.video-player-dialog .el-dialog__body {
  padding: 0;
  background: #f8f9fa;
}

.video-iframe {
  border-radius: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 全局样式 - 确保弹窗居中显示 */
.el-dialog__wrapper.video-player-dialog {
  display: flex !important;
  align-items: center;
  justify-content: center;
}

.el-dialog__wrapper.video-player-dialog .el-dialog {
  position: relative !important;
  margin: 0 !important;
  top: auto !important;
  transform: none !important;
  max-height: 90vh;
  overflow: auto;
}

.el-dialog__wrapper.video-player-dialog {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2000;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .el-dialog__wrapper.video-player-dialog .el-dialog {
    width: 90% !important;
    max-width: 900px;
  }
}

@media (max-width: 768px) {
  .el-dialog__wrapper.video-player-dialog .el-dialog {
    width: 95% !important;
    max-width: none;
    margin: 5vh auto !important;
  }
  
  .el-dialog__wrapper.video-player-dialog .el-dialog__header {
    padding: 15px;
  }
  
  .el-dialog__wrapper.video-player-dialog .el-dialog__title {
    font-size: 14px;
  }
}
</style>

<style scoped>
.error-message {
  margin-top: 10px;
}
.error-message-inline {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80%;
  text-align: center;
}
</style>
